package com.hq.ims.userpc.busservice;

import com.hq.ims.data.config.verification.VdAdd;
import com.hq.ims.data.entity.*;
import com.hq.ims.data.entityenum.EnumFeedbackPhase;
import com.hq.ims.data.entityenum.EnumReceiveStatus;
import com.hq.ims.data.service.*;
import com.hq.ims.data.utils.ErrMsgConstant;
import com.hq.ims.data.utils.PasswordUtils;
import com.hq.ims.data.utils.WebExpandUtils;
import com.hq.ims.data.vo.*;
import com.hq.mybatis.base.page.RequestPage;
import com.hq.utils.exception.CommonException;
import com.hq.utils.util.*;
import com.hq.utils.vo.ReturnVo;
import com.hq.web.utils.SpringBootValidateUtils;
import lombok.NonNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * TODO
 *
 * @author jbp
 * @date 2024/10/14
 */
@Service
public class UserOrganizationStructureService {

    @Value("${userAttribute.userDefaultAvatar}")
    private String initUserAvatar;
    @Resource
    private BaseCompanyService baseCompanyService;
    @Resource
    private BasePermissionMapRoleUserService basePermissionMapRoleUserService;
    @Resource
    private BaseCompanyDepartmentService baseCompanyDepartmentService;
    @Resource
    private BaseUserService baseUserService;
    @Resource
    private BaseCompanyEmployeeService baseCompanyEmployeeService;
    @Resource
    private BaseCompanyDepartmentEmployeeService baseCompanyDepartmentEmployeeService;
    @Resource
    private BasePermissionMapAuthorityDepartmentService basePermissionMapAuthorityDepartmentService;
    @Resource
    private BasePermissionAuthorityService basePermissionAuthorityService;
    @Resource
    private BasePermissionMapAuthorityUserService basePermissionMapAuthorityUserService;
    @Resource
    private BasePermissionRoleService basePermissionRoleService;
    @Resource
    private BaseBusiInfoService baseBusiInfoService;
    @Resource
    private BaseBusInfoNotificationService baseBusInfoNotificationService;
    @Resource
    private BaseBusInfoFeedbackService baseBusInfoFeedbackService;

    /**
     * 获取岗位和对应的用户列表
     * 1.树的各个层都要有用户列表 + 用户数量
     * 2.各个层都要有一个是否为最末节点的标识
     */
    public List<CompanyMapstruct.CompanyTreeVo> getOrgTree(
            @NonNull String companyId,
            @NonNull boolean isShowCompanyDepartment,
            @NonNull boolean isIncludeOneself,
            @NonNull boolean isInclusionChildren
    ) {
        StringUtils.verificationEmpty(companyId, ErrMsgConstant.COMPANY_INFO_NOT_EXISTS);
        List<CompanyMapstruct.CompanyTreeVo> list = baseCompanyService.getCompanyTreeVoByCompanyId(companyId, isShowCompanyDepartment, isIncludeOneself, isInclusionChildren);
        return list;
    }

    /**
     * 添加部门
     */
    public void addDepartment(
            String companyId,
            String companyDepartmentName
    ) {
        //构造验证对象
        CompanyDepartmentMapstruct.SaveVo vo = new CompanyDepartmentMapstruct.SaveVo();
        vo.setCompanyId(companyId);
        vo.setCompanDepartmentName(companyDepartmentName);
        //验证
        SpringBootValidateUtils.validate(vo, VdAdd.class);
        baseCompanyDepartmentService.isExistDepartmentName(vo.getCompanyId(), vo.getCompanDepartmentName(), null);

        //添加部门
        CompanyDepartment companyDepartment = baseCompanyDepartmentService.addDepartment(vo);
        BooleanUtils.isTrueThrow(companyDepartment == null, "添加部门失败,请联系管理员");

    }

    /**
     * 删除部门
     */
    public ReturnVo<Boolean> deleteDepartment(
            String companyId,
            String departmentId
    ) {
        StringUtils.verificationEmpty(departmentId, ErrMsgConstant.DEPARTMENT_INFO_NOT_EXISTS);
        StringUtils.verificationEmpty(companyId, ErrMsgConstant.COMPANY_INFO_NOT_EXISTS);
        baseCompanyDepartmentService.deleteDepartment(departmentId, companyId);
        return ReturnVo.buildSuccess(true);
    }

    /**
     * 更新部门信息
     */
    public Boolean updateDepartment(
            String companyDepartmentId,
            String companyDepartmentName
    ) {
        //攻取公司ID
        String companyId = WebExpandUtils.getHeadCompanyId();
        //构造验证对象
        CompanyDepartmentMapstruct.SaveVo vo = new CompanyDepartmentMapstruct.SaveVo();
        vo.setCompanyDepartmentId(companyDepartmentId);
        vo.setCompanyId(companyId);
        vo.setCompanDepartmentName(companyDepartmentName);
        //验证
        SpringBootValidateUtils.validate(vo, VdAdd.class);
        //是否重名
        baseCompanyDepartmentService.isExistDepartmentName(vo.getCompanyId(), vo.getCompanDepartmentName(), vo.getCompanyDepartmentId());
        //更新
        baseCompanyDepartmentService.updateDepartment(vo);
        return true;
    }


    //------------------------------ 部门操作 ----------------------------------

    /**
     * 根据层级的部门id获取该部门的所有用户
     */
    public List<UserMapstruct.UserAndCompanySimpleVo> getDepartmentAllUserList(String companyDepartmentId) {
        if (StringUtils.isEmpty(companyDepartmentId)) {
            throw CommonException.build(ErrMsgConstant.PARAM_INPUT_ERROR);
        }
        List<UserMapstruct.UserAndCompanySimpleVo> userByDepartmentList = baseCompanyDepartmentEmployeeService.getUserByDepartmentId(companyDepartmentId);
        return userByDepartmentList;
    }

    /**
     * 绑定人员入部门和公司
     */
    @Transactional(rollbackFor = Exception.class)
    public void joinOrg(
            CompanyDepartmentMapstruct.UserJoinDepartment joinDepartment,
            Boolean isPartTimeJob
    ) {
        SpringBootValidateUtils.validate(joinDepartment);
        CompanyDepartment companyDepartment = baseCompanyDepartmentService.getById(joinDepartment.getCompanyDepartmentId());
        ObjectUtils.isNullThrow(companyDepartment, ErrMsgConstant.DEPARTMENT_INFO_NOT_EXISTS);
        //用户加入部门
        baseCompanyDepartmentEmployeeService.joinCompany(
                companyDepartment.getCompanyId(),
                joinDepartment.getUserId(),
                companyDepartment.getCompanyDepartmentId(),
                StringUtils.EMPTY,
                isPartTimeJob
        );
    }

    /**
     * 绑定人员入部门和公司
     */
    @Transactional(rollbackFor = Exception.class)
    public void addUserAndJoinOrg(UserMapstruct.PlatformAddUserVo saveVo) {
        SpringBootValidateUtils.validate(saveVo);
        //验证用户手机号
        boolean bl = baseUserService.mobileExists(saveVo.getMobile(), null);
        BooleanUtils.isTrueThrow(bl, ErrMsgConstant.MOBILE_ALREADY_EXISTS);
        //验证部门
        CompanyDepartment companyDepartment = baseCompanyDepartmentService.getById(saveVo.getCompanyDepartmentId());
        ObjectUtils.isNullThrow(companyDepartment, ErrMsgConstant.DEPARTMENT_INFO_NOT_EXISTS);
        //验证角色
        PermissionRole permissionRole = basePermissionRoleService.getById(saveVo.getPermissionRoleId());
        ObjectUtils.isNullThrow(permissionRole, ErrMsgConstant.PERMISSION_ROLE_NOT_EXISTS);
        BooleanUtils.isFalseThrow(permissionRole.getCompanyId().equals(companyDepartment.getCompanyId()), ErrMsgConstant.PERMISSION_ROLE_NOT_IN_COMPANY);
        //验证密码强度
        boolean pwdReg = PasswordUtils.validRegPwdRB(saveVo.getPwd());
        BooleanUtils.isFalseThrow(pwdReg, ErrMsgConstant.PASSWORD_INTENSITY_LOW);
        //添加用户
        baseUserService.addSimpleUserInfo(
                saveVo.getMobile(),
                saveVo.getMobile(),
                saveVo.getPwd(),
                initUserAvatar,
                saveVo.getRealName()
        );

        //查询用户
        User user = baseUserService.getByMobile(saveVo.getMobile());
        //加入部门
        CompanyDepartmentMapstruct.UserJoinDepartment joinDepartment = new CompanyDepartmentMapstruct.UserJoinDepartment();
        joinDepartment.setCompanyDepartmentId(companyDepartment.getCompanyDepartmentId());
        joinDepartment.setUserId(user.getUserId());
        this.joinOrg(joinDepartment, false);

        //绑定用户角色
        PermissionMapRoleUserMapstruct.BindUserRoleVo bindUserRoleVo = new PermissionMapRoleUserMapstruct.BindUserRoleVo();
        bindUserRoleVo.setUserId(user.getUserId());
        bindUserRoleVo.setPermissionRoleIdList(Arrays.asList(permissionRole.getPermissionRoleId()));
        bindUserRoleVo.setCompanyId(companyDepartment.getCompanyId());
        basePermissionMapRoleUserService.bindUserRole(bindUserRoleVo);
    }

    /**
     * 移动用户的部门
     */
    @Transactional(rollbackFor = Exception.class)
    public void moveUserToOtherDepartment(CompanyDepartmentEmployeeMapstruct.MoveUserVo saveVo) {

        SpringBootValidateUtils.validate(saveVo);

        List<CompanyDepartmentEmployeeMapstruct.MoveUserDetailVo> moveUserVoList = saveVo.getMoveUserDetailVoList();
        List<String> userIdList = moveUserVoList.stream().map(CompanyDepartmentEmployeeMapstruct.MoveUserDetailVo::getUserId).distinct().collect(Collectors.toList());
        String whereToDepartmentId = saveVo.getToDepartmentId();
        String jobName = saveVo.getJobName();

        //查询要调走的部门所属公司id
        CompanyDepartment whereToDepartmentEntity = baseCompanyDepartmentService.getById(whereToDepartmentId);
        ObjectUtils.isNullThrow(whereToDepartmentEntity, ErrMsgConstant.DEPARTMENT_INFO_NOT_EXISTS);

        //移动用户到部门
        baseCompanyDepartmentEmployeeService.moveUserToOtherDepartment(moveUserVoList, whereToDepartmentId, jobName);
    }

    /**
     * 设置公司管理员
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean setCompanyAdmin(String companyId, String userId, Boolean isAdmin) {
        if (StringUtils.isEmpty(companyId)) {
            throw CommonException.build(ErrMsgConstant.PARAM_INPUT_ERROR);
        }
        Company company = baseCompanyService.getById(companyId);
        ObjectUtils.isNullThrow(company, ErrMsgConstant.COMPANY_INFO_NOT_EXISTS);

        boolean bl = baseCompanyEmployeeService.userIsJoinCompany(userId, companyId, true);
        BooleanUtils.isFalseThrow(bl, ErrMsgConstant.USER_IS_NOT_COMPANY_EMPLOYEE);

        //1.清除该公司所有超管身份
        baseCompanyEmployeeService.lambdaUpdate()
                .eq(CompanyEmployee::getCompanyId, companyId)
                .eq(CompanyEmployee::getIsResign, false)
                .set(CompanyEmployee::getIsAdmin, false)
                .update();

        boolean resUpdate = baseCompanyEmployeeService.lambdaUpdate()
                .eq(CompanyEmployee::getUserId, userId)
                .eq(CompanyEmployee::getCompanyId, companyId)
                .eq(CompanyEmployee::getIsResign, false)
                .set(CompanyEmployee::getIsAdmin, isAdmin)
                .update();

        BooleanUtils.isFalseThrow(resUpdate, ErrMsgConstant.OPERATION_FAILURE);
        return resUpdate;
    }

    /**
     * 获取部门的模板角色
     */
    public List<PermissionAuthortyMapstruct.PermissionAuthorityVo> getDepartmentBindAuthList(String companyDepartmentId) {
        StringUtils.verificationEmpty(companyDepartmentId, ErrMsgConstant.DEPARTMENT_INFO_NOT_EXISTS);

        List<String> permissionAuthorityIdList = basePermissionMapAuthorityDepartmentService.getAuthIdListByDeptIdList(Arrays.asList(companyDepartmentId));
        List<PermissionAuthority> permissionAuthorityList = ListUtils.newEmptyList();
        if (ListUtils.isExistsEle(permissionAuthorityIdList)) {
            permissionAuthorityList = basePermissionAuthorityService.lambdaQuery()
                    .in(PermissionAuthority::getPermissionAuthorityId, permissionAuthorityIdList)
                    .list();
        }
        List<PermissionAuthortyMapstruct.PermissionAuthorityVo> voList = PermissionAuthortyMapstruct.INSTANCE.toPermissionAuthorityVoList(permissionAuthorityList);
        return voList;
    }

    /**
     * 修改用户职称
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateJobName(String userId, String departmentId, String jobName) {
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(departmentId) || StringUtils.isEmpty(jobName)) {
            throw CommonException.build(ErrMsgConstant.PARAM_INPUT_ERROR);
        }
        boolean bl = baseCompanyDepartmentEmployeeService.lambdaUpdate()
                .eq(CompanyDepartmentEmployee::getUserId, userId)
                .eq(CompanyDepartmentEmployee::getCompanyDepartmentId, departmentId)
                .set(CompanyDepartmentEmployee::getJobName, StringUtils.isEmpty(jobName) ? StringUtils.EMPTY : jobName)
                .update();

        BooleanUtils.isFalseThrow(bl, ErrMsgConstant.OPERATION_FAILURE);
    }

    /**
     * 根据部门ID获取用户并且分页
     *
     * @param page     分页以象
     * @param searchVo 搜索对象
     */
    public List<UserMapstruct.UserAndCompanySimpleVo> getDepartmentAllUserPage(
            RequestPage page,
            CompanyDepartmentEmployeeMapstruct.PageSearchVo searchVo
    ) {
        List<UserMapstruct.UserAndCompanySimpleVo> userByDepartmentList = baseCompanyDepartmentEmployeeService.getDepartmentAllUserPage(page, searchVo);
        return userByDepartmentList;
    }

    /**
     * 根据部门ID获取用户并且分页
     *
     * @param page     分页以象
     * @param searchVo 搜索对象
     */
    public List<UserMapstruct.UserAndCompanySimpleVo> getCompanyAllUserPage(
            RequestPage page,
            CompanyEmployeeMapstruct.PageSearchVo searchVo
    ) {
        List<UserMapstruct.UserAndCompanySimpleVo> userByDepartmentList = baseCompanyEmployeeService.getCompanyAllUserPage(page, searchVo);
        return userByDepartmentList;
    }

    /**
     * 转换用户对象并胆查询用户的发布和发布忆被接收的
     *
     * @param userAndCompanySimpleVoListList 发布
     */
    public List<UserMapstruct.UserAndCompanyAndSimpleStatisticsSimpleVo> convertUserAndCompanySimpleVoToUserAndCompanyAndSimpleStatisticsSimpleVo(List<UserMapstruct.UserAndCompanySimpleVo> userAndCompanySimpleVoListList) {
        List<UserMapstruct.UserAndCompanyAndSimpleStatisticsSimpleVo> voList = JsonUtils.convertListObject(userAndCompanySimpleVoListList, UserMapstruct.UserAndCompanyAndSimpleStatisticsSimpleVo.class);
        if (ListUtils.isNotExistsEle(voList)) {
            return voList;
        }
        //填充用户发布数据
        for (UserMapstruct.UserAndCompanyAndSimpleStatisticsSimpleVo userAndCompanyAndSimpleStatisticsSimpleVo : voList) {
            userAndCompanyAndSimpleStatisticsSimpleVo.setPublishBusinfoCount(0);
            userAndCompanyAndSimpleStatisticsSimpleVo.setPublishBusinfoBeReceiveCount(0);
            userAndCompanyAndSimpleStatisticsSimpleVo.setFeedBackAlreadyDeliverTenderBeReceiveCount(0);

            //查找发布数量
            List<BusiInfo> busiInfoList = baseBusiInfoService.lambdaQuery()
                    .select(BusiInfo::getBusiInfoId)
                    .eq(BusiInfo::getPublisherId, userAndCompanyAndSimpleStatisticsSimpleVo.getUserId())
                    .eq(BusiInfo::getOrgId, userAndCompanyAndSimpleStatisticsSimpleVo.getCompanyId())
                    .list();
            //设置发布数量
            userAndCompanyAndSimpleStatisticsSimpleVo.setPublishBusinfoCount(busiInfoList.size());

            if (ListUtils.isNotExistsEle(busiInfoList)) {
                continue;
            }
            //查找接收数量
            List<String> busiInfoIdList = busiInfoList.stream().map(BusiInfo::getBusiInfoId).collect(Collectors.toList());
            Long count = baseBusInfoNotificationService.lambdaQuery()
                    .in(BusInfoNotification::getBusiInfoId, busiInfoIdList)
                    .eq(BusInfoNotification::getReceiveStatus, EnumReceiveStatus.Receive)
                    .count();
            userAndCompanyAndSimpleStatisticsSimpleVo.setPublishBusinfoBeReceiveCount(count.intValue());

            //获取被标记为已投标的数量
            Long busiInfoFeedbackAlreadyDeliverTenderCount = baseBusInfoFeedbackService.lambdaQuery()
                    .in(BusInfoFeedback::getBusiInfoId, busiInfoIdList)
                    .eq(BusInfoFeedback::getFeedbackPhase, EnumFeedbackPhase.ProjectAlreadyDeliverTender)
                    .count();
            userAndCompanyAndSimpleStatisticsSimpleVo.setFeedBackAlreadyDeliverTenderBeReceiveCount(busiInfoFeedbackAlreadyDeliverTenderCount.intValue());
        }

        return voList;
    }
}
